#include "memtable.h"

namespace minidb
{

static Slice GetLengthPrefixedSlice(const char *data)
{
    uint32_t len;
    const char *p = data;
    p = GetVarint32Ptr(p, p + 5, &len); // +5: we assume "p" is not corrupted
    return Slice(p, len);
}

int MemTable::KeyComparator::operator()(const char *a, const char *b) const
{
    Slice _a = GetLengthPrefixedSlice(a), _b = GetLengthPrefixedSlice(b);
    return comparator.Compare(_a, _b);
}

MemTable::MemTable(const InternalKeyComparator &comparator) :
    comparator_(comparator),
    refs_(0),
    table_(comparator_, &arena_)
{
}

std::size_t MemTable::ApproximateMemoryUsage()
{
    return arena_.MemoryUsage();
}

Iterator *MemTable::NewIterator()
{
    return new MemTableIterator(&table_);
}

void MemTable::Add(SequenceNumber seq, ValueType type, const Slice &key, const Slice &value)
{
    // Format of an entry is concatenation of:
    //  key_size     : varint32 of internal_key.size()
    //  key bytes    : char[internal_key.size()]
    //  tag          : uint64((sequence << 8) | type)
    //  value_size   : varint32 of value.size()
    //  value bytes  : char[value.size()]
}

bool MemTable::Get(const LookupKey &key, std::string *value, Status *s)
{
    
    // entry format is:
    //    klength  varint32
    //    userkey  char[klength]
    //    tag      uint64
    //    vlength  varint32
    //    value    char[vlength]
    // Check that it belongs to same user key.  We do not check the
    // sequence number since the Seek() call above should have skipped
    // all entries with overly large sequence numbers.
    return false;
}

class MemTableIterator : public Iterator
{
public:
    MemTableIterator(MemTable::Table *table) :
        iter_(table)
    {
    }

    MemTableIterator(const MemTableIterator &) = delete;
    MemTableIterator &operator=(const MemTableIterator &) = delete;

    virtual ~MemTableIterator() = default;

    bool Vaild() const override
    {
        return iter_.Valid();
    };

    void SeekToFirst() override
    {
        return iter_.SeekToFirst();
    };

    void SeekToLast() override
    {
        return iter_.SeekToLast();
    };

    void Seek(const Slice &target) override
    {
        return iter_.Seek(target.ToString().c_str());
    }

    void Next() override
    {
        iter_.Next();
    }

    void Prev() override
    {
        return iter_.Prev();
    }

    Slice key() const override
    {
        return iter_.key();
    }

    Slice value() const override
    {
        /// 为什么value返回的是这个东西？？？
        Slice key_slice = GetLengthPrefixedSlice(iter_.key());
        return GetLengthPrefixedSlice(key_slice.data() + key_slice.size());
    }

    Status status() const override
    {
        return Status::OK();
    };

private:
    MemTable::Table::Iterator iter_;
    std::string tmp_; // For passing to EncodeKey
};

} // namespace minidb